﻿using System;
using System.Web.Http;
using System.Web.Http.Dispatcher;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Castle.Windsor;
using Mvc4Auth;
using User.EF.Model;
using User.Web.Common;
using User.Web.UI.App_Start;
using User.Web.UI.Helper.CastleWindsor;
using User.Web.UI.Helper.MvcBasics;

namespace User.Web.UI
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        /// <summary>
        /// Der Aktuelle Windsor Container
        /// http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container
        /// TODO Wieder private setzten!
        /// </summary>
        private static IWindsorContainer Container { get; set; }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();

            //Zusätzliche ModelBinder registrieren
            AddModelBinder();

            //Nur noch auf die RazorEngine setzten und nicht noch die Default Engine mit erstellen - Verbessert die Performance
            //http://benjamin-abt.de/blog/asp-net-mvc-ungenutzte-viewengines-deaktivieren/
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new RazorViewEngine());

            

            //DB ERSTELLUNG UND ANLEGEN VON TESTDATEN
            //Den aktuellen ConnectionString ermitteln für die DB Verbindung
            string connectionString = new ConnectionStringWeb().GetConnectionString("MainModel");
            //TODO im Livesystem entfernen - DB erstellen, falls diese noch nicht existiert
            MainModelContainer container = new MainModelContainer(connectionString);
            container.Database.CreateIfNotExists();
            //Anlegen von Testdaten und des Standardbenutzers
            CreateBaseData.CreateAdminUser(container);
            CreateBaseData.CreateDefaultUsers(container);

            //CASTLE WINDSOR IoC
            //Erstellen unserer Castle Windsor Instanz die wir im gesamten Projekt benutzten
            Container = new WindsorContainer();
            //Hinzufügen unserer Konfigurationen zum Kontainer.
            Container.Install(new WebInstaller(connectionString), new LoggingInstaller());

            //Erstellen unserer CustomControllerFactory zum Instanziieren der Passenden Controller
            //var customControllerFactory = new CustomControllerFactory(Container);
            //Unsere CustomControllerFactory als Standard Factory zum Erstellen von Controllern setzten, damit diese auch von MVC verwendet wird.
            //ControllerBuilder.Current.SetControllerFactory(customControllerFactory);
            //Um auch in der WebAPI auf Castle Windsor zu benutzen ist folgendes notwendig
            GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new CustomWebApiControllerFactory(Container));

            //Alternative Methode um Di zu realisieren über IDependencyResolver
            DependencyResolver.SetResolver(new WindsorDependencyResolver(Container));
            ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new WindsorControllerActivator(Container)));

            //Für Attribute Routing hinzufügen.
            GlobalConfiguration.Configuration.EnsureInitialized(); 
        }

        protected void Application_End()
        {
            Container.Dispose();
        }

        /// <summary>
        /// Zusätzliche Modelbinder für die Webseite registrieren
        /// </summary>
        private void AddModelBinder()
        {
            //Custom Datetime Modelbinder für DateTime? Values für die Arbeitszeitverwaltung
            ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeModelBinder());
        }

        /// <summary>
        /// Abfangen von Application Errors
        /// </summary>
        protected void Application_Error(object sender, EventArgs e)
        {
            //Dei Fehlermeldung abfangen und dann im ErrorController verarbeiten.
            Exception ex = Server.GetLastError();
            
        }
    }
}